package com.liujun.microserver.auth2.webjoin.server.oauth;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Service
public class AuthorizationCodeTokenService {

	@Autowired
	private AuthorizationCodeConfiguration configuration;

	/**
	 * 编码的字符集
	 */
	private static final String CHARSET_UTF8 = "UTF-8";

	/**
	 * 构造获取code的参数信息
	 * 
	 * @return 构造的参数信息
	 */
	public String getCodeEndPoint() {
		String endPoint = "http://localhost:8080/oauth/authorize";

		Map<String, String> param = new HashMap<>();
		param.put("client_id", "clientapp");
		param.put("response_type", "code");
		param.put("redirect_uri", getEncodedUrl("http://localhost:9001/callback"));
		param.put("scope", getEncodedUrl("read_userinfo"));

		return buildURL(endPoint, param);
	}

	private String buildURL(String endpoint, Map<String, String> parameters) {
		List<String> paramList = new ArrayList<>(parameters.size());

		parameters.forEach((name, value) -> {
			paramList.add(name + "=" + value);
		});

		return endpoint + "?" + paramList.stream().reduce((a, b) -> a + "&" + b).get();
	}

	private String getEncodedUrl(String url) {
		try {
			return URLEncoder.encode(url, CHARSET_UTF8);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * d 通过code获取token
	 * 
	 * @param authorizationCode
	 * @return
	 */
	public OAuth2Token getToken(String authorizationCode) {

		RestTemplate rest = new RestTemplate();
		String baseAuth = configuration.encodeCredentials("clientapp", "112233");

		RequestEntity<MultiValueMap<String, String>> requestEntity = new RequestEntity<>(
				// 消息体部分
				configuration.getBody(authorizationCode),
				// 头部分
				configuration.getHeader(baseAuth), HttpMethod.POST,
				// 验证的地址
				URI.create("http://localhost:8080/oauth/token"));

		// 进行调用
		ResponseEntity<OAuth2Token> responseEntity = rest.exchange(requestEntity, OAuth2Token.class);

		if (responseEntity.getStatusCode().is2xxSuccessful()) {
			return responseEntity.getBody();
		}

		throw new RuntimeException("error trying to retrieve access token");
	}

}
